/**
 * 
 */
package pl.net.beercrm.ws;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.datatype.DatatypeConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import pl.net.beercrm.model.Analysis;
import pl.net.beercrm.model.Customer;
import pl.net.beercrm.model.Ingredient;
import pl.net.beercrm.model.Product;
import pl.net.beercrm.model.Purchase;
import pl.net.beercrm.service.GenericService;
import pl.net.beercrm.service.ProductService;
import pl.net.beercrm.service.PurchaseService;
import pl.net.beercrm.util.DateUtil;
import pl.net.beercrm.ws.model.AnalysisListType;
import pl.net.beercrm.ws.model.AnalysisRequest;
import pl.net.beercrm.ws.model.AnalysisTypeEnum;
import pl.net.beercrm.ws.model.CustomerRequest;
import pl.net.beercrm.ws.model.IngredientType;
import pl.net.beercrm.ws.model.OrderProductInfo;
import pl.net.beercrm.ws.model.OrderRequest;
import pl.net.beercrm.ws.model.ProductProdRequest;

/**
 * @author Rafi
 * 
 */
@Component
public class ObjectProcessor {
	
	private static final Log log = LogFactory.getLog(ObjectProcessor.class);

	@Autowired
	private GenericService<Customer, Long> customerService;

	@Autowired
	private ProductService<Product, Long> productService;

	@Autowired
	private PurchaseService<Purchase, Long> purchaseService;

	public void processCustomerRequest(CustomerRequest object) {
		Customer customer = new Customer();
		customer.setCustomerId(object.getCustomerId());
		customer.setName(object.getName());
		customer.setSurname(object.getSurname());
		if(object.getBirthDate() != null) {
			customer.setBirthDate(DateUtil.xmlToDate(object.getBirthDate()));
		} else {
			customer.setBirthDate(null);
		}
		customer.setRegon(object.getRegon());
		customer.setPesel(object.getPesel());
		customer.setNip(object.getNip());
		customer.setCompanyName(object.getCompanyName());
		customer.setPostalCode(object.getPostalCode());
		customer.setStreet(object.getStreet());
		customer.setCity(object.getCity());
		customer.setState(object.getState());
		customer.setPhone(object.getPhoneNumber());
		customer.setEmail(object.getEmail());

		customerService.upsert(customer);
		log.info("Persisted object: " + customer.toString());
	}

	public void processProductRequest(ProductProdRequest object) {
		Product product = new Product();
		product.setProductId(object.getProductId());
		product.setManufacturer(object.getManufacturer().value());
		product.setName(object.getName());
		product.setType(object.getType());
		product.setCapacity(object.getCapacity());
		product.setBundle(object.getBundle());
		product.setVoltage(object.getVoltage());
		product.setDescription(object.getDescription());
		product.setPrice(object.getPrice());

		productService.upsert(product);

		Set<Ingredient> ingredients = new HashSet<Ingredient>(0);
		for (IngredientType i : object.getIngredients()) {
			Ingredient ingredient = new Ingredient();
			ingredient.setIngredientId(i.getIngredientId());
			ingredient.setName(i.getName());
			ingredient.setAmount(i.getAmount());
			ingredients.add(ingredient);
		}

		productService.upsertIngredients(product, ingredients);
		log.info("Persisted object: " + product.toString());
	}

	public void processPurchaseRequest(OrderRequest object) {
		
		for (OrderProductInfo productInfo : object.getProducts()) {
			Purchase purchase = new Purchase();
			purchase.setPurchaseId(object.getOrderId());
			purchase.setDate(DateUtil.xmlToDate(object.getDate()));

			List<Customer> customers = customerService.findByGuid(object
					.getCustomerId());
			if (customers.size() > 0) {
				Customer customer = customers.get(0);
				purchase.setCustomer(customer);
			}
			
			purchase.setAmount(productInfo.getQuantity());

			List<Product> products = productService.findByGuid(productInfo
					.getProductCode());
			if (products.size() > 0) {
				Product product = products.get(0);
				purchase.setProduct(product);
			}

			purchaseService.upsert(purchase);
			log.info("Persisted object: " + purchase.toString());
		}
	}

	public AnalysisRequest processAnalysis(Analysis analysis) {
		AnalysisRequest analysisRequest = new AnalysisRequest();
		analysisRequest.setCustomerId(analysis.getCustomer());
		try {
			analysisRequest.setDate(DateUtil.dateToXml(analysis.getDate()));
		} catch (DatatypeConfigurationException e) {
			log.error("Conversion between java.util.Date and XMLGregorianCalendar failed!", e);
		}
		
		//Favorite brand
		AnalysisListType favoriteBrand = new AnalysisListType();
		favoriteBrand.setType(AnalysisTypeEnum.FAVORITE_BRAND);
		favoriteBrand.setProductId(analysis.getFavoriteBrand());
		analysisRequest.getAnalysises().add(favoriteBrand);
		
		//Price match
		AnalysisListType priceMatch = new AnalysisListType();
		priceMatch.setType(AnalysisTypeEnum.PRICE_MATCH);
		priceMatch.setProductId(analysis.getPriceMatch());
		analysisRequest.getAnalysises().add(priceMatch);
		
		//Region match
		AnalysisListType regionMatch = new AnalysisListType();
		regionMatch.setType(AnalysisTypeEnum.REGION_MATCH);
		regionMatch.setProductId(analysis.getRegionMatch());
		analysisRequest.getAnalysises().add(regionMatch);
		
		//Ingredient match
		AnalysisListType ingredientMatch = new AnalysisListType();
		ingredientMatch.setType(AnalysisTypeEnum.INGREDIENT_MATCH);
		ingredientMatch.setProductId(analysis.getIngredientMatch());
		analysisRequest.getAnalysises().add(ingredientMatch);
		
		//Global discount
		AnalysisListType globalDiscount = new AnalysisListType();
		globalDiscount.setType(AnalysisTypeEnum.DISCOUNT);
		Integer discount = Integer.valueOf(analysis.getDiscount());
		globalDiscount.setDiscountValue(discount.toString());
		try {
			if(analysis.getDiscountExpiry() != null) {
				globalDiscount.setDiscountExpiry(DateUtil.dateToXml(analysis.getDiscountExpiry()));
			}
		} catch (DatatypeConfigurationException e) {
			log.error("Conversion between java.util.Date and XMLGregorianCalendar failed!", e);
		}
		analysisRequest.getAnalysises().add(globalDiscount);
		
		return analysisRequest;
	}

	public Set<String> getCustomerIds() {
		Set<String> ids = new HashSet<String>(0);
		for (Customer customer : customerService.list()) {
			ids.add(customer.getCustomerId());
		}
		return ids;
	}

}
